<?php
/**
 * Eka Framework 0.3.0
 *
 * @copyright Copyright (c) 2008 Alexey Yu. Chuprina <656b61@gmail.com> (http://php-eka.googlecode.com)
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 *
 * @version $Id$
 */

require_once 'Eka/File.php';

/**
 * Eka_File_Image
 *
 * @package File
 * @subpackage Image
 */
class Eka_File_Image extends Eka_File
{
	const FORMAT_UNKNOWN = 0;
	const FORMAT_GIF = 1;
	const FORMAT_JPEG = 2;
	const FORMAT_PNG = 3;
	
	const RESIZE_LOWER = 1;
	const RESIZE_LARGER = 2;
	
	static protected $fileExtensions = array(
		self::FORMAT_GIF => 'gif',
		self::FORMAT_JPEG => 'jpg',
		self::FORMAT_PNG => 'png'
		);
	
	static protected function hexToRgb($hex)
	{
		return array(
			hexdec(substr($hex, 0, 2)),	//R
			hexdec(substr($hex, 2, 2)),	//G
			hexdec(substr($hex, 4, 2))	//B
		);
	}
	
	static public function getFileExtensionByFormat($format)
	{
		if (key_exists($format, self::$fileExtensions)) {
			return self::$fileExtensions[$format];
		}
		return null;
	}
	
	############################################################################
	
	protected $type = self::TYPE_IMAGE;
	
	protected $width = null;
	protected $height = null;
	protected $format = null;
	
	public function __construct($file)
	{
		parent::__construct($file);
		
		$info = getImageSize($this->file);
		if (!$info) {
			include_once 'Eka/File/Exception.php';
			throw new Eka_File_Exception('The file is not a picture');
		}
		$this->width = $info[0];
		$this->height = $info[1];
		switch ($info[2]) {
			case IMAGETYPE_GIF:
				$this->format = self::FORMAT_GIF;
				break;
			case IMAGETYPE_JPEG:
				$this->format = self::FORMAT_JPEG;
				break;
			case IMAGETYPE_PNG:
				$this->format = self::FORMAT_PNG;
				break;
			default:
				$this->format = self::FORMAT_UNKNOWN;
				break;
		}
	}
	
	public function getFormat()
	{
		return $this->format;
	}
	
	public function getWidth()
	{
		return $this->width;
	}
	
	public function getHeight()
	{
		return $this->height;
	}

	public function convert($format, $jpgQuality = 80)
	{
		if ($this->format === $format) {
			return;
		}
		
		switch ($this->format) {
			case self::FORMAT_GIF:
				$img = imageCreateFromGif($this->file);
				break;
			case self::FORMAT_JPEG:
				$img = imageCreateFromJPEG($this->file);
				break;
			case self::FORMAT_PNG:
				$img = imageCreateFromPng($this->file);
				break;
			default:
				include_once 'Eka/File/Exception.php';
				throw new Eka_File_Exception('Unknown source image format');
		}
		
		$extension = self::getFileExtensionByFormat($format);
		if (null === $extension) {
			include_once 'Eka/File/Exception.php';
			throw new Eka_File_Exception('Unknown format of the resulting image');
		}
		$oldFile = $this->file;
		$this->file = $this->file = $this->getDirectory() . DIRECTORY_SEPARATOR . $this->getBaseName() . '.' . $extension;
		
		switch ($format) {
			case self::FORMAT_GIF:
				imageGif($img, $this->file);
				break;
			case self::FORMAT_JPEG:
				imageJpeg($img, $this->file, $jpgQuality);
				break;
			case self::FORMAT_PNG:
				imagePng($img, $this->file);
				break;
			default:
				include_once 'Eka/File/Exception.php';
				throw new Eka_File_Exception('Unknown resulting image format');
		}
		$this->format = $format;
		
		imageDestroy($img);
		
		if ($oldFile && $this->file !== $oldFile) {
			unlink($oldFile);
		}
	}

	public function resize($width, $height, $out = false, $scrap = false, $zoom = false, $screenColor = 'ffffff', $format = null, $jpgQuality = 80)
	{
		switch ($this->format) {
			case self::FORMAT_GIF:
				$sourceImg = imageCreateFromGif($this->file);
				break;
			case self::FORMAT_JPEG:
				$sourceImg = imageCreateFromJPEG($this->file);
				break;
			case self::FORMAT_PNG:
				$sourceImg = imageCreateFromPng($this->file);
				break;
			default:
				include_once 'Eka/File/Exception.php';
				throw new Eka_File_Exception('Unknown source image format');
		}
		
		$sourceRatio = $this->width / $this->height;
		$ratio = $width / $height;
		
		$zw = $width > $this->width;
		$zh = $height > $this->height;
		
		if ($sourceRatio > $ratio) {
			if ($out) {
				$newHeight = (!$zoom && $zh) ? $this->height: $height;
				$newWidth = $newHeight * $sourceRatio;
				$screenWidth = (!$zoom && $zw && $scrap || $newWidth > $width) ? $width : $newWidth;
				$screenHeight = $scrap ? $height : $newHeight;
			}
			else {
				$newWidth = (!$zoom && $zw) ? $this->width : $width;
				$newHeight = $newWidth / $sourceRatio;
				$screenWidth = (!$zoom && $zw && $scrap) ? $width : $newWidth;
				$screenHeight = $scrap ? $height : $newHeight;
			}
		}
		else if ($sourceRatio < $ratio) {
			if ($out) {
				$newWidth = (!$zoom && $zw) ? $this->width : $width;
				$newHeight = $newWidth / $sourceRatio;
				$screenHeight = (!$zoom && $zh && $scrap || $newHeight > $height) ? $height : $newHeight;
				$screenWidth = $scrap ? $width : $newWidth;
			} else {
				$newHeight = (!$zoom && $zh) ? $this->height: $height;
				$newWidth = $newHeight * $sourceRatio;
				$screenHeight = (!$zoom && $zh && $scrap) ? $height : $newHeight;;
				$screenWidth = $scrap ? $width : $newWidth;
			}
		}
		else {
			$newWidth = (!$zoom && $zw) ? $this->width : $width;
			$newHeight = (!$zoom && $zh) ? $this->height: $height;
			$screenWidth = (!$zoom && $zw && $scrap) ? $width : $newWidth;
			$screenHeight = (!$zoom && $zh && $scrap) ? $height : $newHeight;;
		}
		
		$left = ($screenWidth - $newWidth) / 2;
		$top = ($screenHeight - $newHeight) / 2;

		$screenImg = imageCreateTrueColor($screenWidth, $screenHeight);
		$color = self::hexToRgb($screenColor);
		imageFill($screenImg, 0, 0, imagecolorallocate($screenImg, $color[0], $color[1], $color[2]));
		imageCopyResampled($screenImg, $sourceImg, $left, $top, 0, 0, $newWidth, $newHeight, $this->width, $this->height);
		
		$oldFile = false;
		if ($format !== null && $format !== $this->format) {
			$this->format = $format;
			$extension = self::getFileExtensionByFormat($format);
			if (null === $extension) {
				include_once 'Eka/File/Exception.php';
				throw new Eka_File_Exception('Unknown format of the resulting image');
			}
			$oldFile = $this->file;
			$this->file = $this->file = $this->getDirectory() . DIRECTORY_SEPARATOR . $this->getBaseName() . '.' . $extension;
		}
		
		$this->width = $screenWidth;
		$this->height = $screenHeight;
		
		switch ($this->format) {
			case self::FORMAT_GIF:
				imageGif($screenImg, $this->file);
				break;
			case self::FORMAT_JPEG:
				imageJpeg($screenImg, $this->file, $jpgQuality);
				break;
			case self::FORMAT_PNG:
				imagePng($screenImg, $this->file);
				break;
			default:
				include_once 'Eka/File/Exception.php';
				throw new Eka_File_Exception('Unknown resulting image format');
		}
		
		imageDestroy($sourceImg);
		imageDestroy($screenImg);
		
		if ($oldFile && $this->file !== $oldFile) {
			unlink($oldFile);
		}
	}
}